<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>酒店搜索系统</title>
  <script src="js/vue3.js"></script>
  <script src="js/element-plus.js"></script>
  <script src="js/zh-cn.js"></script>
  <script src="js/icon-vue.js"></script>
  <script src="js/axios.min.js"></script>
  <script src="js/lodash.js"></script>
  <script type="text/javascript">
    window._AMapSecurityConfig = {
      securityJsCode: "2dc743b176ca44e836740dee71aecbae",
    };
  </script>
  <script src="https://webapi.amap.com/loader.js"></script>
  <link rel="stylesheet" href="css/element-plus.css">
  <link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" />
  <link rel="stylesheet" href="css/index.css">
</head>

<body>
  <div id="app">
    <div class="header-title">科泰旅游</div>
    <div class="search-control-container">
      <!-- 搜索表单区域 -->
      <el-header class="search-header">
        <el-card shadow="never" class="search-card">
          
          <el-form :model="searchForm" @submit.prevent="searchHotels">
            <el-row :gutter="20">
              <!-- 关键词 -->
              <el-col :md="6">
                <el-form-item label="搜索酒店">
                  <el-input v-model="searchForm.keyword" placeholder="酒店名/地址/品牌" clearable>
                    <template #prefix>
                      <el-icon>
                        <Search />
                      </el-icon>
                    </template>
                  </el-input>
                </el-form-item>
              </el-col>
              <el-col :md="12">
                <el-button type="primary" native-type="submit" :loading="loading" @click="resetLocation">
                  搜索酒店
                </el-button>
                <el-button @click="openMapDialog">
                  <el-icon>
                    <Location />
                  </el-icon>
                  地图选点搜索<span v-show="searchKeyword != ''">【当前选点：{{searchKeyword}}】</span>
                </el-button>
              </el-col>
            </el-row>
            <el-row :gutter="20" class="filter-containter">
              <!-- 城市 -->
              <el-col :md="6" v-show="!hasTag('city')">
                <el-form-item label="热门城市">
                  <el-select v-model="searchForm.city" clearable placeholder="选择城市"
                    @change="addTag('city', '城市', searchForm.city)">
                    <el-option v-for="city in cityOptions" :key="city" :label="city" :value="city" />
                  </el-select>
                </el-form-item>
              </el-col>
              <!-- 酒店星级 -->
              <el-col :md="6" v-show="!hasTag('minStar')">
                <el-form-item label="酒店星级">
                  <el-select v-model="searchForm.minStar" clearable placeholder="选择最低星级"
                    @change="addTag('minStar', '星级', `${['一','二','三','四','五'][searchForm.minStar-1]}星`)">
                    <el-option v-for="n in 5" :key="n" :label="`${['一','二','三','四','五'][n-1]}星`" :value="n" />
                  </el-select>
                </el-form-item>
              </el-col>

              <!-- 品牌 -->
              <el-col :md="6" v-show="!hasTag('brand')">
                <el-form-item label="热门品牌">
                  <el-select v-model="searchForm.brand" clearable placeholder="选择品牌"
                    @change="addTag('brand', '品牌', searchForm.brand)">
                    <el-option v-for="brand in brandOptions" :key="brand" :label="brand" :value="brand" />
                  </el-select>
                </el-form-item>
              </el-col>

              <!-- 最低评分 -->
              <el-col :md="6" v-show="!hasTag('minScore')">
                <el-form-item label="最低评分">
                  <el-rate v-model="searchForm.minScore" :colors="['#99A9BF', '#F7BA2A', '#FF9900']" :max="5" allow-half
                    @change="addTag('minScore', '最低评分', searchForm.minScore)" />
                </el-form-item>
              </el-col>

              <!-- 价格范围 -->
              <el-col :md="6" >
                <el-form-item label="价格范围">
                  <el-slider v-model="searchForm.priceRange" range :marks="marks" :min="0" :max="4000" :step="100"
                    @change="addTag('priceRange', '价格范围', `${searchForm.priceRange[0]}~${searchForm.priceRange[1]}元`)" />
                </el-form-item>
              </el-col>
              <!-- 筛选标签区域 -->
              <el-col :md="24" class="filter-tags">
                <el-tag class="mr-10 mb-10" v-show="selectedTags.length > 0" closable @close="removeAllTag()"
                  type="warning">筛选条件：</el-tag>
                <el-tag v-for="tag in selectedTags" :key="tag.type" closable @close="removeTag(tag.type, true)" type="info"
                  class="mr-10 mb-10">
                  {{ tag.label }}: {{ tag.value }}
                </el-tag>
              </el-col>
            </el-row>
          </el-form>
        </el-card>
      </el-header>

      <!-- 排序区域 -->
      <el-row class="ctrl-bar">
        <el-col :span="6">
          <el-button-group >
            <el-button :type="sortByPrice ===''? 'default' : 'primary'" value="price" @click="changeSort('price')">
              价格
              <el-icon >
                <svg v-if="sortByPrice === ''" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" data-v-ea893728="">
                  <path fill="currentColor"
                        d="M384 96a32 32 0 0 1 64 0v786.752a32 32 0 0 1-54.592 22.656L95.936 608a32 32 0 0 1 0-45.312h.128a32 32 0 0 1 45.184 0L384 805.632V96zm192 45.248a32 32 0 0 1 54.592-22.592L928.064 416a32 32 0 0 1 0 45.312h-.128a32 32 0 0 1-45.184 0L640 218.496V928a32 32 0 1 1-64 0V141.248z">
                  </path>
                </svg>
                <svg v-if="sortByPrice === 'asc'" class="up" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" data-v-ea893728="">
                  <path fill="currentColor"
                        d="M384 141.248V928a32 32 0 1 0 64 0V218.56l242.688 242.688A32 32 0 1 0 736 416L438.592 118.656A32 32 0 0 0 384 141.248z">
                  </path>
                </svg>
                <svg v-if="sortByPrice === 'desc'" class="down" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" data-v-ea893728="">
                  <path fill="currentColor"
                        d="M576 96v709.568L333.312 562.816A32 32 0 1 0 288 608l297.408 297.344A32 32 0 0 0 640 882.688V96a32 32 0 0 0-64 0z">
                  </path>
                </svg>
              </el-icon>
            </el-button>
            <el-button :type="sortByScore ===''? 'default' : 'primary'" value="score" @click="changeSort('score')">
              评分
              <el-icon >
                <svg v-if="sortByScore === ''" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" data-v-ea893728="">
                  <path fill="currentColor"
                        d="M384 96a32 32 0 0 1 64 0v786.752a32 32 0 0 1-54.592 22.656L95.936 608a32 32 0 0 1 0-45.312h.128a32 32 0 0 1 45.184 0L384 805.632V96zm192 45.248a32 32 0 0 1 54.592-22.592L928.064 416a32 32 0 0 1 0 45.312h-.128a32 32 0 0 1-45.184 0L640 218.496V928a32 32 0 1 1-64 0V141.248z">
                  </path>
                </svg>
                <svg v-if="sortByScore === 'asc'" class="up" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"
                     data-v-ea893728="">
                  <path fill="currentColor"
                        d="M384 141.248V928a32 32 0 1 0 64 0V218.56l242.688 242.688A32 32 0 1 0 736 416L438.592 118.656A32 32 0 0 0 384 141.248z">
                  </path>
                </svg>
                <svg v-if="sortByScore === 'desc'" class="down" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"
                     data-v-ea893728="">
                  <path fill="currentColor"
                        d="M576 96v709.568L333.312 562.816A32 32 0 1 0 288 608l297.408 297.344A32 32 0 0 0 640 882.688V96a32 32 0 0 0-64 0z">
                  </path>
                </svg>
              </el-icon>
            </el-button>
            <el-button :type="sortByStar ===''? 'default' : 'primary'" value="star" @click="changeSort('star')">
              星级
              <el-icon >
                <svg v-if="sortByStar === ''" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" data-v-ea893728="">
                  <path fill="currentColor"
                        d="M384 96a32 32 0 0 1 64 0v786.752a32 32 0 0 1-54.592 22.656L95.936 608a32 32 0 0 1 0-45.312h.128a32 32 0 0 1 45.184 0L384 805.632V96zm192 45.248a32 32 0 0 1 54.592-22.592L928.064 416a32 32 0 0 1 0 45.312h-.128a32 32 0 0 1-45.184 0L640 218.496V928a32 32 0 1 1-64 0V141.248z">
                  </path>
                </svg>
                <svg v-if="sortByStar === 'asc'" class="up" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"
                     data-v-ea893728="">
                  <path fill="currentColor"
                        d="M384 141.248V928a32 32 0 1 0 64 0V218.56l242.688 242.688A32 32 0 1 0 736 416L438.592 118.656A32 32 0 0 0 384 141.248z">
                  </path>
                </svg>
                <svg v-if="sortByStar === 'desc'" class="down" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"
                     data-v-ea893728="">
                  <path fill="currentColor"
                        d="M576 96v709.568L333.312 562.816A32 32 0 1 0 288 608l297.408 297.344A32 32 0 0 0 640 882.688V96a32 32 0 0 0-64 0z">
                  </path>
                </svg>
              </el-icon>
            </el-button>
          </el-button-group>
        </el-col>
        <el-col :span="10" :offset="8"  v-show="hotels.length > 0" class="page-container">
            <el-pagination background layout="total, prev, pager, next" :total="total" :page-size="pageSize"
                           @current-change="handlePageChange" class="pagination-main" />
        </el-col>
      </el-row>
      <div class="hotel-list-container">
        <!-- 酒店列表 -->
        <el-row :gutter="20" class="hotel-list">
          <el-col v-for="hotel in hotels" :key="hotel.id" :xs="24" :sm="12" :md="8" :lg="6" class="hotel-col">
            <el-card class="hotel-card" shadow="hover">
              <el-row>
                <el-col :span="12">
                  <el-image class="hotel-image" :src="hotel.pic" fit="cover" lazy>
                    <template #error>
                      <div class="image-slot">
                        <el-icon>
                          <Picture />
                        </el-icon>
                      </div>
                    </template>
                  </el-image>
                </el-col>
                <el-col :span="8" :offset="4">
                  <div class="hotel-info">
                    <div class="price-info">
                      <span class="price-text">￥{{ hotel.price }}</span>
                      <span>&nbsp;起</span>
                    </div>
                    <el-button type="danger" class="book-button">立刻预定</el-button>
                    <div class="rating-number"><strong>{{ hotel.score }}</strong>/5分</div>
                  </div>
                </el-col>
              </el-row>

              <h2 class="mt-10">{{ hotel.name }}</h2>
              <div class="mt-10">
                <el-tag type="info">{{ hotel.brand }}</el-tag>
                <el-tag class="ml-5">{{ starName(hotel.star) }}</el-tag>
              </div>
              <div class="mt-10 text-secondary">
                <el-icon>
                  <Location />
                </el-icon>
                {{ hotel.address }}
              </div>
            </el-card>
          </el-col>
        </el-row>
      </div>

      </el-main>
    </div>

    <!-- 地图弹窗 -->
    <el-dialog v-model="mapDialogVisible" title="地图位置搜索" width="90%" top="5vh" @opened="initMap">
      <div class="map-container">
        <!-- 地图工具条 -->
        <div class="map-tools">
          <div class="search-box">
            <el-input v-model="searchKeyword" placeholder="输入地点名称（如：北京天安门）" clearable @keyup.enter="handleSearchPlace">
              <template #append>
                <el-button @click="handleSearchPlace">
                  <el-icon>
                    <Search />
                  </el-icon>
                </el-button>
              </template>
            </el-input>

            <div class="radius-control">

              <el-input-number v-model="searchRadius" :min="1" :max="50" controls-position="right"></el-input-number>
              <span class="unit">公里范围</span>
            </div>
          </div>

          <!-- 搜索结果列表 -->
          <div v-if="placeResults.length" class="search-results">
            <div v-for="item in placeResults" :key="item.id" class="result-item" @click="selectPlace(item)">
              <div class="title">{{ item.name }}</div>
              <div class="address">{{ item.address }}</div>
            </div>
          </div>
        </div>

        <!-- 地图容器 -->
        <div id="map" style="height: 65vh;"></div>

        <!-- 操作按钮 -->
        <div class="map-footer">
          <el-button type="primary" @click="confirmLocation">
            搜索此区域酒店（半径 {{ searchRadius }}km）
          </el-button>
          <el-button @click="locateCurrentPosition">
            <el-icon>
              <Position />
            </el-icon>
            我的位置
          </el-button>
        </div>
      </div>
    </el-dialog>
  </div>

  <script>
    const { createApp, ref, reactive, computed } = Vue
    const { ElLoading, ElMessage } = ElementPlus
    const icons = ElementPlusIconsVue // 获取所有图标
    

    const app = createApp({
      setup () {

        // ============= 地图相关 start ===============
        const searchKeyword = ref('')
        const placeResults = ref([])
        const placeSearch = ref(null)
        const geolocation = ref(null)
        const geocoder = ref(null)

        const mapDialogVisible = ref(false)
        const mapInstance = ref(null)
        const marker = ref(null)
        const circle = ref(null)
        const customIcon = ref(null);
        const currentLocation = reactive({
          lnglat: null,
          address: ''
        })
        const searchRadius = ref(5) // 默认搜索半径5公里

        const starName = (star) => {
           let starNames = ['无星级', '一星及以下', '二星级', '三星级', '四星级', '五星级'];
           return starNames[star]
        }
        // 打开地图弹窗
        const openMapDialog = async () => {
          mapDialogVisible.value = true

          initMap()
        }



        // 初始化地图
        const initMap = () => {
          AMapLoader.load({
            key: "09f8b6857b56fbdbe04f2cb1f1a1573e", //申请好的Web端开发者key，调用 load 时必填
            version: "2.0", //指定要加载的 JS API 的版本，缺省时默认为 1.4.15
          })
            .then((AMap) => {

              //JS API 加载完成后获取AMap对象
              mapInstance.value = new AMap.Map('map', {
                zoom: 12,
                center: [116.397428, 39.90923]
              })

              // 添加地图点击事件
              mapInstance.value.on('click', (e) => {
                updateLocation(e.lnglat)

                geocoder.value.getAddress(e.lnglat, (status, result) => {
                  if (status === 'complete') {
                    currentLocation.address = result.regeocode.formattedAddress
                  }
                })
              })
              // 自定义图标
              customIcon.value = new AMap.Icon({
                size: new AMap.Size(20, 20),  // 设置图标的大小
                image: 'https://webapi.amap.com/theme/v1.3/markers/b/mark_bs.png',  // 设置自定义图片的路径
                imageSize: new AMap.Size(20, 20)  // 设置图片的实际显示尺寸
              });

              AMap.plugin('AMap.Geocoder', function () {
                mapInstance.value.plugin(['AMap.Geocoder'], () => {
                  geocoder.value = new AMap.Geocoder({
                    radius: 1000,
                    extensions: 'all'
                  })

                })
              });

              AMap.plugin('AMap.Geolocation', function() {
                geolocation.value = new AMap.Geolocation({
                  // 是否使用高精度定位，默认：true
                  enableHighAccuracy: true,
                  // 设置定位超时时间，默认：无穷大
                  timeout: 10000,
                  //  定位成功后调整地图视野范围使定位位置及精度范围视野内可见，默认：false
                  zoomToAccuracy: true,
                })
              })

              AMap.plugin('AMap.PlaceSearch', function () {
                // 初始化地点搜索服务
                placeSearch.value = new AMap.PlaceSearch({
                  pageSize: 5,
                  pageIndex: 1
                })
              });
            })
            .catch((e) => {
              console.error(e); //加载错误提示
            });


        }

        const clearMapOverlays = () => {
          mapInstance.value.clearMap();
        }

        // 更新选点位置
        const updateLocation = (lnglat) => {
          currentLocation.lnglat = lnglat

          // 清除旧标记
          if (marker.value) {
            marker.value.setMap(null)
          }
          if (circle.value) {
            circle.value.setMap(null)
          }

          // 添加新标记
          marker.value = new AMap.Marker({
            icon: customIcon.value,
            position: lnglat,
            map: mapInstance.value
          })

          // 添加范围圈
          circle.value = new AMap.Circle({
            center: lnglat,
            radius: searchRadius.value * 1000,
            strokeColor: "#FF33FF",
            strokeOpacity: 1,
            strokeWeight: 2,
            fillColor: "#1791fc",
            fillOpacity: 0.4
          })
          circle.value.setMap(mapInstance.value)

          // 调整地图视野
          mapInstance.value.setFitView([circle.value])
        }

        // 确认搜索位置
        const confirmLocation = () => {
          if (!currentLocation.lnglat) {
            ElMessage.warning('请先在地图上选择位置')
            return
          }

          // 将坐标转换到ES的geo_point格式
          searchForm.location = {
            lat: currentLocation.lnglat.lat,
            lon: currentLocation.lnglat.lng
          }
          searchForm.radius = searchRadius.value
          searchForm.keyword = '';  // 清空关键字，因为是通过地图定位的

          mapDialogVisible.value = false
          searchHotels()
        }

        // 地点搜索处理
        const handleSearchPlace = _.debounce(async () => {
          if (!searchKeyword.value.trim()) {
            placeResults.value = []
            return
          }

          try {
            const result = await new Promise((resolve, reject) => {
              placeSearch.value.search(searchKeyword.value, (status, result) => {
                status === 'complete' ? resolve(result) : reject(status)
              })
            })

            placeResults.value = result.poiList.pois.map(poi => ({
              id: poi.id,
              name: poi.name,
              address: poi.address,
              location: poi.location
            }))
          } catch (error) {
            ElMessage.error('地点搜索失败：' + error)
            placeResults.value = []
          }
        }, 500)

        // 选择地点
        const selectPlace = (item) => {
          // 清除旧标记
          clearMapOverlays()

          // 创建新标记
          const lnglat = new AMap.LngLat(item.location.lng, item.location.lat)
          updateLocation(lnglat)
          searchKeyword.value = item.name;
          // 移动地图视图
          mapInstance.value.setCenter(lnglat)
          mapInstance.value.setZoom(15)
        }

        // 定位当前位置
        const locateCurrentPosition = () => {
          clearMapOverlays()
          geolocation.value.getCurrentPosition((status, result) => {
            if (status === 'complete') {
              const lnglat = new AMap.LngLat(
                result.position.lng,
                result.position.lat
              )
              updateLocation(lnglat)
              mapInstance.value.setCenter(lnglat)
            } else {
              ElMessage.error('定位失败：' + result.message)
            }
          })
        }

        // ============= 地图相关 end ===============

        // ============= 查询相关 start =============
        const brandOptions = ref(['豪生', '希尔顿', '万豪', '如家']) // 从后端获取
        const cityOptions = ref(['北京', '上海', '广州', '深圳', '杭州']) // 城市选项
        const loading = ref(false)
        const total = ref(0)
        const pageSize = ref(10)
        const currentPage = ref(1)
        const marks = ref({
          0: "0", 2000: "2000", 4000: "4000"
        })

        // 已选标签
        const selectedTags = ref([])


        // 搜索表单数据
        const searchForm = reactive({
          keyword: '',
          city: '',
          priceRange: [0, 4000],
          minScore: '',
          minStar: '',
          brand: '',
          location: {
            lat: '',
            lon: ''
          },
          radius: 5
        })

        // 添加标签
        const addTag = (type, label, value) => {
          if (!value || (Array.isArray(value) && value.length === 0)) {
            removeTag(type)
            return
          }
          const existingIndex = selectedTags.value.findIndex(t => t.type === type)
          if (existingIndex >= 0) {
            selectedTags.value[existingIndex].value = value
          } else {
            selectedTags.value.push({ type, label, value })
          }
          searchHotels();
        }

        // 移除标签
        const removeTag = (type, reSearch) => {
          selectedTags.value = selectedTags.value.filter(t => t.type !== type)
          if (type === 'city') searchForm.city = ''
          if (type === 'priceRange') searchForm.priceRange = [0, 4000]
          if (type === 'minScore') searchForm.minScore = ''
          if (type === 'minStar') searchForm.minStar = ''
          if (type === 'brand') searchForm.brand = ''
          if(reSearch === true) {
            searchHotels()
          }
        }

        const removeAllTag = () =>{
          selectedTags.value.forEach(tag => {
            // 删除标签，但是不重新查询
            removeTag(tag.type, false)
          });
          // 全部删除完成再查询
          searchHotels()
        }

        const hasTag = (type) => {
          return selectedTags.value.find(t => t.type === type)
        }

        // 酒店数据
        const hotels = ref([])

        const resetLocation = () => {
          searchKeyword.value = '';
          searchForm.searchKeyword = ''
          searchForm.location.lat = ''
          searchForm.location.lon = ''
        }
        // 搜索方法
        const searchHotels = async () => {
          const loadingInstance = ElLoading.service({ fullscreen: true })
          try {
            const params = {
              page: currentPage.value,
              size: pageSize.value
            }
            if(searchForm.keyword){
              // 通过关键字搜索，直接拼接在params中
              params.keyword = searchForm.keyword
              // 按关键字搜索，经纬度置空
              resetLocation();
            }
            if (searchForm.location.lat && searchForm.location.lon) {
              // 通过经纬度搜索，直接拼接在params中
              params.lon = searchForm.location.lon
              params.lat = searchForm.location.lat
              params.radius = searchForm.radius
            }
            // 筛选条件：品牌、星级、评分、城市、价格范围
            if(searchForm.brand){
              params.brand = searchForm.brand
            }
            if(searchForm.minStar > 0) {
              params.minStar = searchForm.minStar
            }
            if (searchForm.city) {
              params.city = searchForm.city
            }
            if (searchForm.minScore > 0) {
              params.minScore = searchForm.minScore
            }
            if (searchForm.priceRange && searchForm.priceRange.length === 2) {
              params.minPrice = searchForm.priceRange[0]
              params.maxPrice = searchForm.priceRange[1]
            }
            // 排序条件
            params.sortByPrice = sortByPrice.value;
            params.sortByScore = sortByScore.value;
            params.sortByStar = sortByStar.value;
            params.sortBy = sortBy.join(',');

            const response = await axios.post('/api/hotel/search', params)
            hotels.value = response.data.list
            total.value = response.data.total
          } catch (error) {
            ElMessage.error('搜索失败：' + error.message)
          } finally {
            loadingInstance.close()
          }
        }

        // 分页处理
        const handlePageChange = (page) => {
          currentPage.value = page
          searchHotels()
        }
        // ============= 查询相关 end =============

        // ============= 排序相关 start =============
        const sortBy = []
        const sortByPrice = ref('')
        const sortByScore = ref('')
        const sortByStar = ref('') // 排序方向: asc/desc
        // 处理排序变化
        const changeSort = (type) => {
          let typeIdx = sortBy.indexOf(type);
          if(typeIdx < 0) {
            sortBy.push(type);
          } else {
            sortBy.splice(typeIdx, 1); // 先删除原来的
            sortBy.push(type); // 再添加最新的，保证排序优先级
          }
          let sortValue = ['', 'asc', 'desc'];
          let idx;
          switch(type){
            case "price":
              idx = sortValue.indexOf(sortByPrice.value);
              idx = ++idx % sortValue.length;
              sortByPrice.value = sortValue[idx];
              break;
            case "score":
              idx = sortValue.indexOf(sortByScore.value);
              idx = ++idx % sortValue.length;
              sortByScore.value = sortValue[idx];
              break;
            case "star":
              idx = sortValue.indexOf(sortByStar.value);
              idx = ++idx % sortValue.length;
              sortByStar.value = sortValue[idx];
              break;
          }
          // 触发搜索
          searchHotels()
        }
        // ============= 排序相关 end =============


        return {
          starName,
          // 地图
          searchKeyword,
          placeResults,
          handleSearchPlace,
          selectPlace,
          locateCurrentPosition,
          mapDialogVisible,
          searchRadius,
          openMapDialog,
          resetLocation,
          confirmLocation,
          // 查询
          loading,
          searchForm,
          cityOptions,
          hotels,
          marks,
          total,
          pageSize,
          searchHotels,
          handlePageChange,
          selectedTags,
          addTag,
          removeTag,
          hasTag,
          removeAllTag,
          // 排序
          brandOptions,
          sortByPrice,
          sortByScore,
          sortByStar,
          changeSort,
        }
      }
    })
    

    // 全局注册所有图标
    for (const [name, component] of Object.entries(icons)) {
      app.component(name, component)
    }

    app.use(ElementPlus, {
      locale : ElementPlusLocaleZhCn
    }).mount('#app')


  </script>
</body>

</html>